package com.ruoyi.common.utils.uuid;

import java.io.Serializable;
import java.util.Calendar;
import java.util.Random;

public class LongId implements Comparable<LongId>, Serializable {
    private static final long TIME_MAX_VALUE = 4294967295L;
    private static final int RANDOM_MAX_VALUE = 65535;
    private static final int INSTANCE_ID_MAX_VALUE = 32767;
    private static long _baseTime = 0L;
    private static int _defaultInstanceId;
    private static int _totalCounter;
    private static long _lastTime = 0L;
    private static Object _syncObject = new Object();
    private long _currentTime;
    private int _currentCounter;
    private int _instanceId = 0;

    private void generateNewCounter() {
        Object var1 = _syncObject;
        synchronized(_syncObject) {
            _totalCounter = (_totalCounter + 1) % '\uffff';
            this._currentTime = this.getCurrentTimeValue();
            if(0 == _totalCounter) {
                for(; _lastTime == this._currentTime; this._currentTime = this.getCurrentTimeValue()) {
                    try {
                        Thread.sleep(50L);
                    } catch (InterruptedException var4) {
                        throw new IllegalArgumentException(var4.toString());
                    }
                }
            }

            this._currentCounter = _totalCounter;
            _lastTime = this._currentTime;
        }
    }

    private long getCurrentTimeValue() {
        return System.currentTimeMillis() / 1000L - _baseTime;
    }


    public LongId() {
        this._instanceId = _defaultInstanceId;
        this.generateNewCounter();
    }

    public long toLong() {
        long result = this._currentTime;
        if(result > 4294967295L) {
            throw new IllegalArgumentException("Time overflow!");
        } else {
            result <<= 31;
            long newCounter = (long)this._currentCounter;
            newCounter <<= 15;
            result = result | newCounter | (long)this._instanceId;
            return result;
        }
    }


    public String toString() {
        return Long.toString(this.toLong());
    }

    public static LongId get() {
        return new LongId();
    }


    public int compareTo(LongId id) {
        if(id == null) {
            return -1;
        } else {
            long ret = this.toLong() - id.toLong();
            return 0L == ret?0:(ret > 0L?1:-1);
        }
    }



    static {
        Calendar c = Calendar.getInstance();
        c.set(2014, 4, 21, 0, 0, 0);
        _baseTime = c.getTime().getTime() / 1000L;
        _defaultInstanceId = Math.abs((new Random()).nextInt());
        _defaultInstanceId %= 32767;
        _totalCounter = Math.abs((new Random()).nextInt());
    }
}
